package com.rd.project.service;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.LineSeparator;
import com.rd.project.model.Klas;
import com.rd.project.model.Score;
import com.rd.project.model.Student;
import com.rd.project.model.Test;
import com.rd.project.model.Vak;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import static javax.ejb.TransactionAttributeType.REQUIRES_NEW;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

@Stateless
public class DataServiceImpl implements DataService {

    @PersistenceContext
    private EntityManager em;

    private static Font titleFont = new Font(Font.FontFamily.TIMES_ROMAN, 20, Font.BOLD);

    @TransactionAttribute(REQUIRES_NEW)
    public List<Klas> getAlleKlassen() {
        Query q = em.createNamedQuery("Klas.getAlleKlassen");
        return (List<Klas>) q.getResultList();
    }

    @TransactionAttribute(REQUIRES_NEW)
    public List<Vak> getAlleVakkenFromKlas(int klasId) {
        Query q = em.createNamedQuery("Vak.getAlleVakkenFromKlas");
        q.setParameter("klas", klasId);
        return (List<Vak>) q.getResultList();
    }

    @TransactionAttribute(REQUIRES_NEW)
    public List<Test> getAlleTestenFromVak(int vakId) {
        Query q = em.createNamedQuery("Test.getAlleTestenFromVak");
        q.setParameter("vak", vakId);
        return (List<Test>) q.getResultList();
    }

    @TransactionAttribute(REQUIRES_NEW)
    public List<Score> getAlleScoresFromTest(int testId) {
        Query q = em.createNamedQuery("Score.getAlleScoresFromTest");
        q.setParameter("testId", testId);
        return (List<Score>) q.getResultList();
    }

    @TransactionAttribute(REQUIRES_NEW)
    public Test getTest(int testId) {
        Query q = em.createNamedQuery("Test.getTest");
        q.setParameter("id", testId);
        return (Test) q.getSingleResult();
    }

    @TransactionAttribute(REQUIRES_NEW)
    public Student getStudent(int studentId) {
        Query q = em.createNamedQuery("Student.getStudent");
        q.setParameter("id", studentId);
        return (Student) q.getSingleResult();
    }

    @TransactionAttribute(REQUIRES_NEW)
    public Klas getKlas(int klasId) {
        Query q = em.createNamedQuery("Klas.getKlas");
        q.setParameter("id", klasId);
        return (Klas) q.getSingleResult();
    }

    @TransactionAttribute(REQUIRES_NEW)
    public Vak getVak(int vakId) {
        Query q = em.createNamedQuery("Vak.getVak");
        q.setParameter("id", vakId);
        return (Vak) q.getSingleResult();
    }

    @Override
    public void genereerPdfTest(int testId)
            throws DocumentException, IOException {
        //Maak een nieuw document aan
        Document document = new Document();

        //Temp file aanmaken
        File temp = File.createTempFile("test_rapport", ".pdf");

        //PDF Genereren
        PdfWriter.getInstance(document, new FileOutputStream(temp.getAbsolutePath()));

        //Document openen
        document.open();

        //Inhoud toevoegen
        document.add(new Paragraph("Rapport", titleFont));
        document.add(new Paragraph("Test: " + getTest(testId).getNaam()));

        document.add(new Paragraph("Klas: " + getKlas(getVak(
                getTest(testId).getVakId().intValue()).getKlasId()).getNaam()
        ));
        document.add(new Paragraph("Vak: " + getVak(
                getTest(testId).getVakId().intValue()).getNaam()
        ));

        PdfPTable table = new PdfPTable(3);
        table.setSpacingBefore(10.0f);
        table.addCell("Test");
        table.addCell("Student");
        table.addCell("Score");

        for (int i = 0; i < getAlleScoresFromTest(testId).size(); i++) {
            table.addCell(getTest(testId).getNaam());
            table.addCell(getStudent(getAlleScoresFromTest(testId).get(i).getStudentId().intValue()).getNaam());
            table.addCell("" + getAlleScoresFromTest(testId).get(i).getScore());
        }

        document.add(table);

        //Document sluiten
        document.close();

        exportPdf(temp);
    }

    @Override
    public void genereerPdfKlas(int klasId)
            throws DocumentException, IOException {
        //Maak een nieuw document aan
        Document document = new Document();

        //Temp file aanmaken
        File temp = File.createTempFile("klas_rapport", ".pdf");

        //PDF Genereren
        PdfWriter.getInstance(document, new FileOutputStream(temp.getAbsolutePath()));

        //Document openen
        document.open();

        //Inhoud toevoegen
        document.add(new Paragraph("Rapport", titleFont));

        document.add(new Paragraph("Klas: " + getKlas(klasId).getNaam()));

        PdfPTable table = new PdfPTable(3);
        table.setSpacingBefore(10.0f);
        table.addCell("Test");
        table.addCell("Student");
        table.addCell("Score");

        List<Vak> vakken = getAlleVakkenFromKlas(klasId);
        List<Test> testen = new ArrayList<Test>();

        //alle testen ophalen van alle vakken
        for (int i = 0; i < vakken.size(); i++) {
            testen.addAll(getAlleTestenFromVak(vakken.get(i).getId().intValue()));
        }

        for (int i = 0; i < testen.size(); i++) {
            for (int j = 0; j < getAlleScoresFromTest(testen.get(i).getId().intValue()).size(); j++) {
                table.addCell(testen.get(i).getNaam());
                table.addCell(getStudent(getAlleScoresFromTest(testen.get(i).getId().intValue()).get(j).getStudentId().intValue()).getNaam());
                table.addCell("" + getAlleScoresFromTest(testen.get(i).getId().intValue()).get(j).getScore());
            }
        }

        document.add(table);

        //Document sluiten
        document.close();

        exportPdf(temp);
    }

    @Override
    public void genereerPdfVak(int vakId)
            throws DocumentException, IOException {
        
        //Maak een nieuw document aan
        Document document = new Document();

        //Temp file aanmaken
        File temp = File.createTempFile("klas_rapport", ".pdf");

        //PDF Genereren
        PdfWriter.getInstance(document, new FileOutputStream(temp.getAbsolutePath()));

        //Document openen
        document.open();

        //Inhoud toevoegen
        document.add(new Paragraph("Rapport", titleFont));

        document.add(new Paragraph("Klas: " + getKlas(getVak(vakId).getKlasId()).getNaam()));
        document.add(new Paragraph("Vak: " + getVak(vakId).getNaam()));
        PdfPTable table = new PdfPTable(3);
        table.setSpacingBefore(10.0f);
        table.addCell("Test");
        table.addCell("Student");
        table.addCell("Score");
        List<Test> testen = getAlleTestenFromVak(vakId);

        for (int i = 0; i < testen.size(); i++) {
            for (int j = 0; j < getAlleScoresFromTest(testen.get(i).getId().intValue()).size(); j++) {
                table.addCell(testen.get(i).getNaam());
                table.addCell(getStudent(getAlleScoresFromTest(testen.get(i).getId().intValue()).get(j).getStudentId().intValue()).getNaam());
                table.addCell("" + getAlleScoresFromTest(testen.get(i).getId().intValue()).get(j).getScore());
            }
        }

        document.add(table);

        //Document sluiten
        document.close();

        exportPdf(temp);
        
    }

    @Override
    public void exportPdf(File temp) throws FileNotFoundException, IOException {
        FacesContext fc = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) fc.getExternalContext().getResponse();

        response.setHeader("Content-Disposition", "attachment; filename=rapport.pdf");
        response.setContentLength((int) temp.length());

        ServletOutputStream out = null;

        FileInputStream input = new FileInputStream(temp);
        byte[] buffer = new byte[1024];
        out = response.getOutputStream();
        int i = 0;
        while ((i = input.read(buffer)) != -1) {
            out.write(buffer);
            out.flush();
        }

        fc.responseComplete();
    }
}
